#include "uart_port.h"

// 全局串口设备实例
static uart_device_t g_uart_dev;

// 环形缓冲区初始化
static void ring_buffer_init(ring_buffer_t *rb, uint8_t *buffer, uint16_t size)
{
    rb->buffer = buffer;
    rb->size = size;
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
}

// 环形缓冲区写入
static uint16_t ring_buffer_write(ring_buffer_t *rb, const uint8_t *data, uint16_t len)
{
    uint16_t bytes_written = 0;

    for (uint16_t i = 0; i < len; i++)
    {
        if (rb->count < rb->size)
        {
            rb->buffer[rb->head] = data[i];
            rb->head = (rb->head + 1) % rb->size;
            rb->count++;
            bytes_written++;
        }
        else
        {
            break; // 缓冲区满
        }
    }

    return bytes_written;
}

// 环形缓冲区读取
static uint16_t ring_buffer_read(ring_buffer_t *rb, uint8_t *data, uint16_t len)
{
    uint16_t bytes_read = 0;

    for (uint16_t i = 0; i < len; i++)
    {
        if (rb->count > 0)
        {
            data[i] = rb->buffer[rb->tail];
            rb->tail = (rb->tail + 1) % rb->size;
            rb->count--;
            bytes_read++;
        }
        else
        {
            break; // 缓冲区空
        }
    }

    return bytes_read;
}

// 获取环形缓冲区可用空间
static uint16_t ring_buffer_available(ring_buffer_t *rb)
{
    return rb->size - rb->count;
}

// 获取环形缓冲区数据量
static uint16_t ring_buffer_data_count(ring_buffer_t *rb)
{
    return rb->count;
}

// 串口异步初始化
void uart_async_init(uart_device_t *dev, UART_HandleTypeDef *huart,
                     uint8_t *rx_buf, uint16_t rx_size,
                     uint8_t *tx_buf, uint16_t tx_size)
{
    dev->huart = huart;
    dev->tx_busy = 0;

    // 初始化环形缓冲区
    ring_buffer_init(&dev->rx_buffer, rx_buf, rx_size);
    ring_buffer_init(&dev->tx_buffer, tx_buf, tx_size);

    // 启动串口接收中断
    HAL_UART_Receive_IT(dev->huart, &dev->rx_buffer.buffer[dev->rx_buffer.head], 1);
}

// 串口写入函数
unsigned int uart_write(uart_device_t *dev, const void *buf, unsigned int len)
{
    if (dev == NULL || buf == NULL || len == 0)
    {
        return 0;
    }

    const uint8_t *data = (const uint8_t *)buf;
    unsigned int bytes_written = 0;

    // 将数据写入发送缓冲区
    bytes_written = ring_buffer_write(&dev->tx_buffer, data, len);

    // 如果发送空闲，启动发送
    if (!dev->tx_busy && ring_buffer_data_count(&dev->tx_buffer) > 0)
    {
        uint8_t tx_data;
        if (ring_buffer_read(&dev->tx_buffer, &tx_data, 1) > 0)
        {
            dev->tx_busy = 1;
            HAL_UART_Transmit_IT(dev->huart, &tx_data, 1);
        }
    }

    return bytes_written;
}

// 串口读取函数
unsigned int uart_read(uart_device_t *dev, void *buf, unsigned int len)
{
    if (dev == NULL || buf == NULL || len == 0)
    {
        return 0;
    }

    uint8_t *data = (uint8_t *)buf;

    // 从接收缓冲区读取数据
    return ring_buffer_read(&dev->rx_buffer, data, len);
}

// 串口接收完成回调
void uart_rx_callback(uart_device_t *dev)
{
    if (dev == NULL)
        return;

    // 将接收到的数据存入环形缓冲区
    uint8_t received_data;
    if (ring_buffer_available(&dev->rx_buffer) > 0)
    {
        received_data = dev->rx_buffer.buffer[dev->rx_buffer.head];
        ring_buffer_write(&dev->rx_buffer, &received_data, 1);
    }

    // 重新启动接收中断
    HAL_UART_Receive_IT(dev->huart, &dev->rx_buffer.buffer[dev->rx_buffer.head], 1);
}

// 串口发送完成回调
void uart_tx_callback(uart_device_t *dev)
{
    if (dev == NULL)
        return;

    // 检查是否还有数据要发送
    if (ring_buffer_data_count(&dev->tx_buffer) > 0)
    {
        uint8_t tx_data;
        if (ring_buffer_read(&dev->tx_buffer, &tx_data, 1) > 0)
        {
            HAL_UART_Transmit_IT(dev->huart, &tx_data, 1);
        }
        else
        {
            dev->tx_busy = 0;
        }
    }
    else
    {
        dev->tx_busy = 0;
    }
}

// 全局函数指针实现
unsigned int uart_global_write(const void *buf, unsigned int len)
{
    return uart_write(&g_uart_dev, buf, len);
}

unsigned int uart_global_read(void *buf, unsigned int len)
{
    return uart_read(&g_uart_dev, buf, len);
}

// 定义全局函数指针
unsigned int (*write)(const void *buf, unsigned int len) = uart_global_write;
unsigned int (*read)(void *buf, unsigned int len) = uart_global_read;
